package io.yuncheng.modules.sys.entity;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.yuncheng.common.utils.CollectionUtils;
import io.yuncheng.common.utils.NumberUtil;
import lombok.Data;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 汇总
 *
 * @author jared
 * @email 15721509625@163.com
 * @date 2020-11-28 17:28:02
 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SubAppLogCollectVo implements Serializable {
    /**
     * 最外层
     */
    private VoEntity total;
    /**
     * 最外层
     */
    private VoDateEntity dateEntity;

    private Map<String, Integer> stringIntegerMap;
    /**
     * 详情数据
     */
    private Map<Date, Integer> data;
    /**
     *
     */
    private Map<Date, Map<String, Integer>> mapData;


    private List<VoDateEntity> list;

    private List<VoEntity> totalList;

    private String detailName;

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class VoEntity {
        private String key;
        private Integer value = 0 ;
    }

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class VoDateEntity implements Comparable<VoDateEntity> {
        private Date date;
        private Integer value;
        private List<Map> list;

        @Override
        public int compareTo(VoDateEntity o) {
            return o.getDate().compareTo(this.getDate());
        }
    }

    public void putData(Date k, Integer v) {
        this.total.setValue(NumberUtil.integerAdd(v, total.getValue()));
        this.getData().put(k, v);
    }


    public String totalKey(){
        return getTotal().getKey();
    }
    public void putMapData(Date k, String str, Integer value) {
        this.total.setValue(NumberUtil.integerAdd(value, total.getValue()));
        CollectionUtils.putMapAdd(this.getStringIntegerMap(),str,value);
        if (!this.getMapData().containsKey(k)) {
            Map<String, Integer> objectObjectHashMap = new HashMap<>(4);
            this.getMapData().put(k, objectObjectHashMap);
        }
        CollectionUtils.putMapAdd(this.getMapData().get(k),str,value);

    }


    public static SubAppLogCollectVo initBuildInterface(String value,String detail) {
        SubAppLogCollectVo subAppLogCollectVo = initBuildInterface(value);
        if(detail!=null){
            subAppLogCollectVo.setDetailName(detail + value);
        }
        return subAppLogCollectVo;
    } public static SubAppLogCollectVo initBuildInterface(String value) {
        SubAppLogCollectVo voNum = new SubAppLogCollectVo();
        SubAppLogCollectVo.VoEntity voNumEntity = new SubAppLogCollectVo().new VoEntity();
        Map<Date, Integer> map = new HashMap<>(16);

        Map<Date, Map<String, Integer>> mapDate = new HashMap<>(16);
        Map<String, Integer> strMap = new HashMap<>(16);
        voNum.setStringIntegerMap(strMap);
        voNumEntity.setKey(value);
        voNum.setTotal(voNumEntity);
        voNum.setData(map);
        voNum.setMapData(mapDate);
        return voNum;
    }
    public void onlyAddTotal(SubAppLogCollectVo entity){
        VoEntity total = entity.getTotal();
        VoEntity newTotal = this.getTotal();
        //总次数
        newTotal.setValue(NumberUtil.integerAdd(total.getValue(), newTotal.getValue()));
    }
    public void add(SubAppLogCollectVo entity) {
        VoEntity total = entity.getTotal();
        VoEntity newTotal = this.getTotal();
        //总次数
        newTotal.setValue(NumberUtil.integerAdd(total.getValue(), newTotal.getValue()));
        Map<Date, Integer> data = entity.getData();
        data.forEach((k, v) -> CollectionUtils.putMapAdd(this.getData(),k,v));
        Map<Date, Map<String, Integer>> mapData = entity.getMapData();
        Map<Date, Map<String, Integer>> mapTotalData = this.getMapData();
        mapData.forEach((k, v) -> {
            if (!mapTotalData.containsKey(k)) {
                Map<String, Integer> map = new HashMap<>(4);
                mapTotalData.put(k, map);
            }
            v.forEach((k1, v1) -> CollectionUtils.putMapAdd(mapTotalData.get(k),k1,v1));
        });
        Map<String, Integer> mapStrData = entity.getStringIntegerMap();
        Map<String, Integer> mapStrTotalData = this.getStringIntegerMap();
        mapStrData.forEach((k1, v1) -> CollectionUtils.putMapAdd(mapStrTotalData, k1, v1));
    }

    public SubAppLogCollectVo buildMapForList() {
        Map<Date, Integer> data = this.getData();
        List<VoDateEntity> list = new ArrayList<>();
        if(data!=null) {
            data.forEach((k, v) -> {
                VoDateEntity entity = new VoDateEntity();
                entity.setDate(k);
                entity.setValue(v);
                list.add(entity);
            });
        }
        Collections.sort(list);


        this.setList(list);
        this.setData(null);

        Map<Date, Map<String, Integer>> mapData = this.getMapData();
        if (!ObjectUtils.isEmpty(mapData)) {
            List<VoDateEntity> list2 = new ArrayList<>();
            mapData.forEach((k, v) -> {
                VoDateEntity entity = new VoDateEntity();
                entity.setDate(k);

                List<Map> list1 = new ArrayList<>();

                v.forEach((k1, v1) -> {
                    Map<String, String> map = new HashMap<>(4);
                    map.put("key", k1);
                    map.put("value", v1.toString());
                    list1.add(map);
                });
                entity.setList(list1);
                list2.add(entity);
            });
            this.setList(list2);
        }
        Map<String, Integer> mapMap = this.getStringIntegerMap();
        List<VoEntity> list3 = new ArrayList<>();
        if(mapMap!=null){
            mapMap.forEach((k,v)->{
                VoEntity entity = new VoEntity();
                entity.setKey(k);
                entity.setValue(v);
                list3.add(entity);
            });
        }
        this.setTotalList(list3);
        if(ObjectUtils.isEmpty(this.getTotalList())){
            this.setTotalList(null);
        }
        this.setStringIntegerMap(null);
        this.setMapData(null);
        return this;
    }

    /**
     * 只累加total
     * @param vo
     */
    public void addTotalList(SubAppLogCollectVo vo){
        if(this.getTotalList() == null){
            this.setTotalList(new ArrayList<>());
        }
        if(vo!=null && vo.getTotal()!=null){
            VoEntity total = new VoEntity();
            total.setKey(vo.getTotal().getKey());
            total.setValue(vo.getTotal().getValue());
            this.getTotal().setValue(NumberUtil.integerAdd(this.getTotal().getValue(),vo.getTotal().getValue()));
            this.getTotalList().add(total);
        }
    }
    public SubAppLogCollectVo cleanMap(){
        this.setMapData(null);
        this.setData(null);
        this.setList(null);
        this.setStringIntegerMap(null);
        return this;
    }
    public List<SubAppLogCollectVo> changeListDateKeyToStrKey(){
        this.buildMapForList();
        List<SubAppLogCollectVo> list = new ArrayList<>();
        getTotalList().forEach(a->{
            SubAppLogCollectVo subAppLogCollectVo = SubAppLogCollectVo.initBuildInterface(a.getKey(),getTotal().getKey());
            list.add(subAppLogCollectVo);
        });
        Map<String, SubAppLogCollectVo> collect = list.stream().collect(Collectors.toMap(SubAppLogCollectVo::totalKey, a -> a));
        List<VoDateEntity> dateDate = getList();
        dateDate.forEach(a->{
            List<Map> dateStrData = a.getList();
            dateStrData.forEach(b-> {
                Object key = b.get("key");
                SubAppLogCollectVo subAppLogCollectVo = collect.get(key);
                if(subAppLogCollectVo!=null){
                    subAppLogCollectVo.putData(a.getDate(), Integer.valueOf(b.get("value").toString()));
                }
            });
        });
        list.forEach(a->a.buildMapForList());
        return list;
    }
}
